package com.hqd.ch03.v25.utils;

import com.hqd.ch03.v25.jdbc.datasource.ConnectionHolder;
import com.hqd.ch03.v25.tx.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public abstract class DataSourceUtils {
    public static Connection getConnection(DataSource dataSource) throws SQLException {
        return doGetConnection(dataSource);
    }

    private static Connection doGetConnection(DataSource dataSource) throws SQLException {
        Object resource = TransactionSynchronizationManager.getResource(dataSource);
        if (resource instanceof Connection) {
            return (Connection) resource;
        }

        Connection con = dataSource.getConnection();
        TransactionSynchronizationManager.bindResource(dataSource, con);
        return con;
    }


    public static void releaseConnection(Connection con, DataSource dataSource) {
        try {
            doReleaseConnection(con, dataSource);
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {
        if (con == null) {
            return;
        }
        if (dataSource != null) {
            ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
            if (conHolder != null && connectionEquals(conHolder, con)) {
                conHolder.released();
                return;
            }
        }
        doCloseConnection(con, dataSource);
    }

    private static boolean connectionEquals(ConnectionHolder conHolder, Connection passedInCon) {
        if (!conHolder.hasConnection()) {
            return false;
        }
        Connection heldCon = conHolder.getConnection();
        return (heldCon == passedInCon || heldCon.equals(passedInCon));
    }

    public static void doCloseConnection(Connection con, DataSource dataSource) throws SQLException {
        con.close();
    }
}
